/**
 * 
 */
package com.fare.taluo.util.excel.engine.xmlparse.impl;

import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.fare.taluo.util.excel.engine.module.ExcelModel;
import com.fare.taluo.util.excel.engine.module.PropertyModel;
import com.fare.taluo.util.excel.engine.module.SheetData;
import com.fare.taluo.util.excel.engine.module.SheetModel;
import com.fare.taluo.util.excel.engine.xmlparse.XmlParse;

/**
 * @author keman 项目二部-信息化应用中心-广东数据通信网络有限公司.
 * @version version, 2007-11-23 下午03:55:01
 * @since from version 1.1
 */
public class Dom4jParseImpl implements XmlParse {

	private Document doc = null;
	public Dom4jParseImpl(File file) {
		try {
			SAXReader reader = new SAXReader();
			doc = reader.read(file);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public Dom4jParseImpl(String path) {
		try {
			SAXReader reader = new SAXReader();
			doc = reader.read(new File(path));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 将xml的excel配置解析成ExcelModel对象，并将其放入到map中
	 * 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private Map<String, ExcelModel> parseExcel() {
		Iterator<Element> excelIt = doc.selectNodes("/excel-mapping/excel")
				.iterator();
		Map<String, ExcelModel> map = new HashMap<String, ExcelModel>();
		// 解析xml配置中的excel元素
		while (excelIt.hasNext()) {
			Element excelElement = excelIt.next();
			ExcelModel excelModel = parseExcelModel(excelElement);

			// 解析xml配置中的sheet元素
			Iterator<Element> sheetIt = excelElement.elementIterator();
			while (sheetIt.hasNext()) {
				Element sheetElement = sheetIt.next();
				SheetModel sm = parseSheetModel(sheetElement);

//				// 解析xml配置中的tittles元素
//				Iterator<Element> titlesIt = sheetElement
//						.elementIterator("titles");
//				if (titlesIt.hasNext()) {
//					Element titlesElement = titlesIt.next();
//					Iterator<Element> titleIt = titlesElement.elementIterator();
//					while (titleIt.hasNext()) {
//						Element titleElement = titleIt.next();
//						sm.getTitles().add(parseSheetTitle(titleElement));
//					}
//				}
				// 解析xml配置中的data元素
				Iterator<Element> dataIt = sheetElement.elementIterator("data");
				while (dataIt.hasNext()) {
					Element dataElement = dataIt.next();
					SheetData sd = parseSheetData(dataElement);
					// 解析xml配置中的data元素的子元素
					Iterator<Element> propertyModelIt = dataElement.elementIterator();
					while (propertyModelIt.hasNext()) {
						Element propertyModelEle = propertyModelIt.next();
						sd.getPropertyModels().add((PropertyModel)setBeanProperty(propertyModelEle,PropertyModel.class));
					}
					sm.getDatas().add(sd);
					sm.getDataMap().put(sd.getId(), sd);
				}
				excelModel.getSheets().add(sm);
				excelModel.getSheetMap().put(sm.getId(), sm);
			}
			map.put(excelModel.getId(), excelModel);
		}
		return map;
	}

	/**
	 * 将xml配置文件中的data元素解析成sheetData对象
	 * 
	 * @param childElement：
	 *            xml配置文件中的excel元素
	 * @return
	 */
	private SheetData parseSheetData(Element childElement) {
		SheetData sheetData= (SheetData)setBeanProperty(childElement,SheetData.class);
		return sheetData;
	}

	

	/**
	 * 将xml配置文件中的excel元素解析成ExcelModel对象
	 * 
	 * @param childElement：
	 *            xml配置文件中的excel元素
	 * @return
	 */
	private ExcelModel parseExcelModel(Element childElement) {
		ExcelModel excelModel= (ExcelModel)setBeanProperty(childElement,ExcelModel.class);
		return excelModel;
	}

	/**
	 * 将xml配置文件中的sheet元素解析成sheetModel对象
	 * 
	 * @param childElement：
	 *            xml配置文件中的sheet元素
	 * @return
	 */
	private SheetModel parseSheetModel(Element childElement) {
		SheetModel sheetModel= (SheetModel)setBeanProperty(childElement,SheetModel.class);
		return sheetModel;
	}

	
	/**
	 * 将xml配置文件中元素属性设置到对象上
	 * @param childElement
	 * @param clazz
	 * @return
	 */
	private Object setBeanProperty(Element childElement,Class clazz){
		Object obj =null;
		try {
			obj= clazz.newInstance();
			Field[] field = clazz.getDeclaredFields();
			for(Field f : field){
				//集合属性和map属性不参与xml的配置中的属性设置
				if(!f.getType().equals(String.class)){
					continue;
				}
//				System.out.println("set"+f.getName().substring(0,1).toUpperCase()+f.getName().substring(1));
//				System.out.println("================"+ childElement.attributeValue(f.getName()));
				Method setter =clazz.getMethod("set"+f.getName().substring(0,1).toUpperCase()+f.getName().substring(1), String.class);
				setter.invoke(obj, childElement.attributeValue(f.getName()));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	
		return obj;
	}

	public Map<String, ExcelModel> parseXml() {
		return parseExcel();
	}

}
